package fiuba.algo3.algothief;

import java.util.ArrayList;
import java.util.Iterator;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class ConfiguracionInicial {

	private int numeroCiudadesCriminal;
	private int cantidadDeLugares;
	private ArrayList<Ciudad> ciudadesNoVisitadasPorCriminal;
	private ArrayList<Ciudad> ciudadesCriminal;
	private Criminal criminal;
	private ArrayList<Criminal> criminales;
	private ArrayList<String> caracteristicasCriminal;
	private ArrayList<String> seniasCriminales;
	private ArrayList<String> sexosCriminales;
	private ArrayList<String> hobbiesCriminales;
	private ArrayList<String> vehiculosCriminales;
	private ArrayList<String> pelosCriminales;
	


	public ConfiguracionInicial(Jugador jugador) {
		this.numeroCiudadesCriminal = 5;
		this.criminales = new ArrayList<Criminal>();
		this.caracteristicasCriminal = new ArrayList<String>();
		this.sexosCriminales = new ArrayList<String>();
		this.seniasCriminales = new ArrayList<String>();
		this.hobbiesCriminales = new ArrayList<String>();
		this.vehiculosCriminales = new ArrayList<String>();
		this.pelosCriminales = new ArrayList<String>();
		
		this.criminal = null;
		this.ciudadesCriminal = new ArrayList<Ciudad>();
		this.ciudadesNoVisitadasPorCriminal = new ArrayList<Ciudad>();
		this.cantidadDeLugares = 3;
	}
	public ConfiguracionInicial(JugadorNovato jugador) {
		this.numeroCiudadesCriminal = 5;
		this.criminales = new ArrayList<Criminal>();
		this.caracteristicasCriminal = new ArrayList<String>();
		this.sexosCriminales = new ArrayList<String>();
		this.seniasCriminales = new ArrayList<String>();
		this.hobbiesCriminales = new ArrayList<String>();
		this.vehiculosCriminales = new ArrayList<String>();
		this.pelosCriminales = new ArrayList<String>();
		this.criminal = null;
		this.ciudadesCriminal = new ArrayList<Ciudad>();
		this.ciudadesNoVisitadasPorCriminal = new ArrayList<Ciudad>();
		this.cantidadDeLugares = 3;
	}
	
	public ConfiguracionInicial(JugadorDetective jugador) {
		this.numeroCiudadesCriminal = 6;
		this.criminales = new ArrayList<Criminal>();
		this.caracteristicasCriminal = new ArrayList<String>();
		this.sexosCriminales = new ArrayList<String>();
		this.seniasCriminales = new ArrayList<String>();
		this.hobbiesCriminales = new ArrayList<String>();
		this.vehiculosCriminales = new ArrayList<String>();
		this.pelosCriminales = new ArrayList<String>();
		
		this.criminal = null;
		this.ciudadesCriminal = new ArrayList<Ciudad>();
		this.ciudadesNoVisitadasPorCriminal = new ArrayList<Ciudad>();
		this.cantidadDeLugares = 3;
	}
	public ConfiguracionInicial(JugadorInvestigador jugador) {
		this.numeroCiudadesCriminal = 7;
		this.criminales = new ArrayList<Criminal>();
		this.caracteristicasCriminal = new ArrayList<String>();
		this.sexosCriminales = new ArrayList<String>();
		this.seniasCriminales = new ArrayList<String>();
		this.hobbiesCriminales = new ArrayList<String>();
		this.vehiculosCriminales = new ArrayList<String>();
		this.pelosCriminales = new ArrayList<String>();
		
		this.criminal = null;
		this.ciudadesCriminal = new ArrayList<Ciudad>();
		this.ciudadesNoVisitadasPorCriminal = new ArrayList<Ciudad>();
		this.cantidadDeLugares = 3;
	}
	public ConfiguracionInicial(JugadorSargento jugador) {
		this.numeroCiudadesCriminal = 8;
		this.criminales = new ArrayList<Criminal>();
		this.caracteristicasCriminal = new ArrayList<String>();
		this.sexosCriminales = new ArrayList<String>();
		this.seniasCriminales = new ArrayList<String>();
		this.hobbiesCriminales = new ArrayList<String>();
		this.vehiculosCriminales = new ArrayList<String>();
		this.pelosCriminales = new ArrayList<String>();
		
		this.criminal = null;
		this.ciudadesCriminal = new ArrayList<Ciudad>();
		this.ciudadesNoVisitadasPorCriminal = new ArrayList<Ciudad>();
		this.cantidadDeLugares = 3;
	}
	
	
	public void levantarConfiguracionInicial(Document docCiudades,Document docCriminales){
		this.generarListaCiudadesCriminalYNoVisitadasPorCriminal(docCiudades);
		this.cargarPistasACiudadesCriminalYCiudadesNoVisitadasPorCriminal(docCiudades);
		this.generarListaCriminales(docCriminales);
		this.elegirCriminalRandom();
		this.cargarListaPistasCriminal(this.criminal);
		this.agregarDatosCriminalEnPrimerasCincoCiudadesCriminal();
		this.cargarListasDeAtributosCriminales(docCriminales);
	}


	private void generarListaCiudadesCriminalYNoVisitadasPorCriminal(Document doc) {
		ArrayList<Ciudad> todasLasCiudades = new ArrayList<Ciudad>();
		Element elementoCiudades = (Element) doc.getElementsByTagName("Ciudades").item(0);
		for (int i = 0; i < elementoCiudades.getChildNodes().getLength(); i++) {
			Ciudad ciudad = Ciudad.hidratar(elementoCiudades.getChildNodes().item(i));
			todasLasCiudades.add(ciudad);
		}
		for (int j = 0; j < todasLasCiudades.size(); j++) {
			Ciudad ciudad = todasLasCiudades.get(j).duplicar();
			this.ciudadesNoVisitadasPorCriminal.add(ciudad);
		}
		for (int i = 0; i < this.numeroCiudadesCriminal; i++) {
			int numeroRandom = (int) (Math.random() * this.ciudadesNoVisitadasPorCriminal.size());
			this.ciudadesCriminal.add(this.ciudadesNoVisitadasPorCriminal.get(numeroRandom));
			this.ciudadesNoVisitadasPorCriminal.remove(numeroRandom);
		}
	}

	
	private String encontrarElementoRandom(String Padre,String hijo,Document doc){
		Element Hobbies = (Element) doc.getElementsByTagName(Padre).item(0);
		int numeroRandom = (int) (Math.random() * Hobbies.getChildNodes().getLength());
		String devolucion = (((Element) Hobbies.getChildNodes().item(numeroRandom)).getAttribute(hijo));
		return devolucion;
	}
	
	
	private int encontrarCiudadXML(Ciudad ciudad, Document doc) {
		String nombre = ciudad.getNombre();
		Element ciudades = (Element) doc.getElementsByTagName("Ciudades").item(0);
		int indice = 0;
		boolean seEncontro = false;
		while (indice < ((Node) ciudades).getChildNodes().getLength()
				&& (!seEncontro)) {
			if (nombre.equalsIgnoreCase(((Element) ciudades.getChildNodes().item(indice)).getAttribute("nombre"))) {
				seEncontro = true;
			} else {
				indice += 1;
			}
		}
		return indice;
	}

	
	private void cargarPistasACiudadesCriminalYCiudadesNoVisitadasPorCriminal(Document doc) {
		this.cargarCiudadesPorLasQueElCriminalNoHaPasado(doc);
		Element ciudades = (Element) doc.getElementsByTagName("Ciudades").item(0);
		Iterator<Ciudad> i = this.ciudadesCriminal.iterator();
		Ciudad ciudadAnterior = i.next();
		Ciudad ciudadActual = null;
		while (i.hasNext()) {
			ciudadActual = i.next();
			int indice = this.encontrarCiudadXML(ciudadActual, doc);
			Element ciudadXML = (Element) ciudades.getChildNodes().item(indice);
			Element lugares = (Element) ciudadXML.getChildNodes().item(0);
			for (int j = 0; j < this.cantidadDeLugares; j++) {
				Element lugarXML = (Element) lugares.getChildNodes().item(j);
				Lugar lugarCreado = new Lugar(lugarXML.getAttribute("nombre"));
				this.cargarPistasAlLugar(lugarCreado, lugarXML);
				ciudadAnterior.agregarLugar(lugarCreado);
			}
			ciudadAnterior = ciudadActual;
		}
		Lugar lugarFalso = new Lugar("Aeropuerto");
		lugarFalso.agregarPista(new PistaLadron("facil", "ladron"));
		lugarFalso.agregarPista(new PistaLadron("media", "ladron"));
		lugarFalso.agregarPista(new PistaLadron("dificil", "ladron"));
		ciudadActual.agregarLugar(lugarFalso);
		lugarFalso = new Lugar("Muelle");
		lugarFalso.agregarPista(new PistaCuchillo("facil", "cuchillo"));
		lugarFalso.agregarPista(new PistaCuchillo("media", "cuchillo"));
		lugarFalso.agregarPista(new PistaCuchillo("dificil", "cuchillo"));
		ciudadActual.agregarLugar(lugarFalso);
		lugarFalso = new Lugar("Bolsa");
		lugarFalso.agregarPista(new PistaBalazo("facil", "balazo"));
		lugarFalso.agregarPista(new PistaBalazo("media", "balazo"));
		lugarFalso.agregarPista(new PistaBalazo("dificil", "balazo"));
		ciudadActual.agregarLugar(lugarFalso);
	}

	
	private void cargarCiudadesPorLasQueElCriminalNoHaPasado(Document doc) {
		
		Element ciudades = (Element) doc.getElementsByTagName("Ciudades").item(0);
		for (int i = 0; i < this.ciudadesNoVisitadasPorCriminal.size(); i++) {
			Ciudad ciudadActual = ciudadesNoVisitadasPorCriminal.get(i);
			int indice = this.encontrarCiudadXML(ciudadActual, doc);
			Element ciudadUltimaXML = (Element) ciudades.getChildNodes().item(indice);
			Element lugares = (Element) ciudadUltimaXML.getChildNodes().item(0);
			for(int j=0;j<3;j++){
				Lugar lugarFalso = new Lugar(((Element) lugares.getChildNodes().item(j)).getAttribute("nombre"));
				this.cargarPistasSinContenido(lugarFalso);
				ciudadActual.agregarLugar(lugarFalso);
			}
		}
	}
	

	private void cargarPistasSinContenido(Lugar lugarFalso) {
		lugarFalso.agregarPista(new PistaOrdinaria("facil","No ha pasado por aqui."));
		lugarFalso.agregarPista(new PistaOrdinaria("media","No ha pasado por aqui."));
		lugarFalso.agregarPista(new PistaOrdinaria("dificil","No ha pasado por aqui."));
	}

	
	private void cargarPistasAlLugar(Lugar lugarCreado, Element lugarXML) {

		String contenidoDePista = this.obtenerContenidoDePista(0, lugarXML);
		Pista pista = new PistaOrdinaria("facil", contenidoDePista);
		lugarCreado.agregarPista(pista);

		contenidoDePista = this.obtenerContenidoDePista(1, lugarXML);
		pista = new PistaOrdinaria("media", contenidoDePista);
		lugarCreado.agregarPista(pista);

		contenidoDePista = this.obtenerContenidoDePista(2, lugarXML);
		pista = new PistaOrdinaria("dificil", contenidoDePista);
		lugarCreado.agregarPista(pista);
	}

	
	private String obtenerContenidoDePista(int i, Element lugarXML) {
		Element pistas = (Element) lugarXML.getChildNodes().item(i);
		int numeroRandom = (int) (Math.random() * pistas.getChildNodes().getLength());
		Element pista = (Element) pistas.getChildNodes().item(numeroRandom);
		return pista.getAttribute("contenido");
	}
	
	
	private void generarListaCriminales(Document docCriminales){
		int i=0;
		while(i<10){
			Criminal criminal=randomCriminal(docCriminales, i);
			boolean criminalNoRepetido = true;
			int j=0;
			while(j<criminales.size()&& !criminalNoRepetido){
				criminalNoRepetido = criminal.comparar(criminales.get(j));
				j++;
			}
			if(criminalNoRepetido){
				criminales.add(criminal);
				i++;
			}
		}
	}
	
	
	private Criminal randomCriminal(Document doc, int numeroDeCriminal) {
		Criminal criminal = new Criminal("", "", "", "", "", "");
		Element Sexos = (Element) doc.getElementsByTagName("Sexos").item(0);
		int numeroRandom = (int) (Math.random() * Sexos.getChildNodes().getLength());
		Element Sexo = (Element) Sexos.getChildNodes().item(numeroRandom);
		String sexoAsetear = (Sexo.getAttribute("sexo"));
		criminal.setSexo(sexoAsetear);
		String nombreAsetear = (((Element) Sexo.getChildNodes().item(numeroDeCriminal)).getAttribute("nombre"));
		criminal.setNombre(nombreAsetear);
		String peloAsetear = encontrarElementoRandom("Pelos","pelo",doc);
		criminal.setCabello(peloAsetear);
		String seniaAsetear = encontrarElementoRandom("Senias","senia",doc);
		criminal.setSenia(seniaAsetear);
		String vehiculoAsetear = encontrarElementoRandom("Vehiculos","vehiculo",doc);
		criminal.setVehiculo(vehiculoAsetear);
		String hobbyAsetear = encontrarElementoRandom("Hobbies","hobby",doc);
		criminal.setHobby(hobbyAsetear);
		return criminal;
	}

	
	private void elegirCriminalRandom(){
			int numeroRandom = (int) (Math.random() * criminales.size());
			this.criminal=criminales.get(numeroRandom);
	}
	
	
	private void cargarListaPistasCriminal(Criminal criminal){
		this.caracteristicasCriminal.add("El sexo del criminal es: " + criminal.getSexo());
		this.caracteristicasCriminal.add("Tiene pelo color:  " + criminal.getCabello());
		this.caracteristicasCriminal.add("Tiene como senia un:  " + criminal.getSenia());
		this.caracteristicasCriminal.add("Se mueve en:  " + criminal.getVehiculo());
		this.caracteristicasCriminal.add("Tiene por hobby:  " + criminal.getHobby());
	}

	
	private void agregarDatosCriminalEnPrimerasCincoCiudadesCriminal() {
		int indice = 0;
		Iterator<Ciudad> i = this.ciudadesCriminal.iterator();
		while (i.hasNext() && (indice < 5)) {
			Ciudad ciudadActual = i.next();
			int lugarAleatoreo = (int) (Math.random() * 3);
			Lugar lugarAInsertarPistas = ciudadActual.getLugar(lugarAleatoreo);
			int caracteristicaCriminalAleatorea = (int) (Math.random() * this.caracteristicasCriminal.size());
			Jugador jugadorNovato = new JugadorNovato(null, ciudadActual, 0, null);
			Pista pista = lugarAInsertarPistas.getPista((JugadorNovato) jugadorNovato);
			pista.setContenido(pista.getContenido() + " " + this.caracteristicasCriminal.get(caracteristicaCriminalAleatorea));
			Jugador jugadorDetective = new JugadorDetective(null, ciudadActual, 0, null);
			pista = lugarAInsertarPistas.getPista((JugadorDetective) jugadorDetective);
			pista.setContenido(pista.getContenido() + " " + this.caracteristicasCriminal.get(caracteristicaCriminalAleatorea));
			Jugador jugadorInvestigador = new JugadorInvestigador(null, ciudadActual, 0, null);
			pista = lugarAInsertarPistas.getPista((JugadorInvestigador) jugadorInvestigador);
			pista.setContenido(pista.getContenido() + " " + this.caracteristicasCriminal.get(caracteristicaCriminalAleatorea));
			this.caracteristicasCriminal.remove(caracteristicaCriminalAleatorea);
			indice += 1;
		}
	}
	
	
	private void cargarListasDeAtributosCriminales(Document docCriminales) {
		this.cargarCaracteristica("Sexos","sexo", docCriminales, this.sexosCriminales);
		this.cargarCaracteristica("Senias","senia", docCriminales, this.seniasCriminales);
		this.cargarCaracteristica("Hobbies","hobby", docCriminales,  this.hobbiesCriminales);
		this.cargarCaracteristica("Vehiculos","vehiculo", docCriminales,  this.vehiculosCriminales);
		this.cargarCaracteristica("Pelos","pelo", docCriminales,  this.pelosCriminales);		
	}
	
	
	private void cargarCaracteristica(String padre,String hijo,Document docCriminal, ArrayList<String> lista){
		Element caracteristicas = (Element) docCriminal.getElementsByTagName(padre).item(0);
		for(int i = 0; i < caracteristicas.getChildNodes().getLength(); i++){
			Element caracteristica = (Element) caracteristicas.getChildNodes().item(i);
			lista.add(caracteristica.getAttribute(hijo));
		}
	}
	

	public ArrayList<String> getVehiculosCriminales() {
		return this.vehiculosCriminales;
	}
	
	
	public ArrayList<String> getSeniasCriminales() {
		return this.seniasCriminales;
	}
	
	
	public ArrayList<String> getSexosCriminales() {
		return this.sexosCriminales;
	}
	
	
	public ArrayList<String> getHobbiesCriminales() {
		return this.hobbiesCriminales;
	}
	
	
	public ArrayList<String> getPelosCriminales() {
		return this.pelosCriminales;
	}
	
	
	public Criminal getCriminal() {
		return this.criminal;
	}
	
	
	public ArrayList<Ciudad> getCiudadesCriminal() {
		return this.ciudadesCriminal;
	}

	
	public ArrayList<Ciudad> getCiudadesNoVisitadasPorCriminal() {
		return this.ciudadesNoVisitadasPorCriminal;
	}


	public ArrayList<Criminal> getCriminales() {
		return this.criminales;
	}
	

}
